package cn.com.duiba.millionaire.center.biz.service.impl;

import cn.com.duiba.millionaire.center.api.constant.RedisKeyFactory;
import cn.com.duiba.millionaire.center.api.dto.MillionaireConsumerDto;
import cn.com.duiba.millionaire.center.api.enums.AccountTypeEnum;
import cn.com.duiba.millionaire.center.biz.bo.ConsumeAccountInfoParam;
import cn.com.duiba.millionaire.center.biz.bo.ConsumeAccountParam;
import cn.com.duiba.millionaire.center.biz.dao.MillionaireConsumerAccountRecordDao;
import cn.com.duiba.millionaire.center.biz.dao.MillionaireConsumerDao;
import cn.com.duiba.millionaire.center.biz.dao.TableHelper;
import cn.com.duiba.millionaire.center.biz.entity.MillionaireConsumerAccountRecordEntity;
import cn.com.duiba.millionaire.center.biz.service.UserAccountService;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;

/**
 * Created by sty on 1/23/18.
 */
@Service
public class UserAccountServiceImpl implements UserAccountService {

    @Resource(name = "redisTemplate")
    private RedisTemplate<String, MillionaireConsumerDto> redisTemplate;

    @Autowired
    private MillionaireConsumerDao millionaireConsumerDao;

    @Autowired
    private MillionaireConsumerAccountRecordDao millionaireConsumerAccountRecordDao;


    private String buildConsumerKey(Long consumerId) {
        return RedisKeyFactory.K008.toString() + consumerId;
    }


    @Override
    public void addConsumerAccount(ConsumeAccountParam consumeRenascenceParam) {
        if (consumeRenascenceParam == null) {
            return;
        }
        checkParam(consumeRenascenceParam);

        List<ConsumeAccountInfoParam> totalInfo = Lists.newArrayList();
        totalInfo.addAll(consumeRenascenceParam.getCidAppIdSet().stream().map(user -> {
            ConsumeAccountInfoParam param = new ConsumeAccountInfoParam();
            param.setActivityId(consumeRenascenceParam.getActivityId());
            param.setAmount(consumeRenascenceParam.getAmount());
            param.setCid(user.getValue0());
            param.setAppId(user.getValue1());
            return param;
        }).collect(Collectors.toList()));

        //异步增加用户流水记录
        //异步增加复活卡使用记录

        List<MillionaireConsumerAccountRecordEntity> records = totalInfo.stream()
                .map(one -> {
                    MillionaireConsumerAccountRecordEntity record = new MillionaireConsumerAccountRecordEntity();
                    record.setConsumerId(one.getCid());
                    record.setBizId(String.valueOf(one.getActivityId()));
                    record.setBizType(AccountTypeEnum.WIN_INCOME.getCode());
                    record.setAmount(one.getAmount());
                    record.setAppId(one.getAppId());
                    return record;
                }).collect(Collectors.toList());
        int  ret = millionaireConsumerAccountRecordDao.batchInsert(records);

        if(ret<=0){
            return;
        }
        //同步增加用户的流水，并清除用户的缓存
        Map<String, List<ConsumeAccountInfoParam>> userPrefix = Maps.newHashMap();

        totalInfo.stream().forEach(one -> {
            String prefix = TableHelper.getTableSuffix(one.getCid());
            List<ConsumeAccountInfoParam> origin = userPrefix.get(prefix);
            if (origin == null) {
                userPrefix.put(prefix, Lists.newArrayList(one));
            } else {
                origin.add(one);
                userPrefix.put(prefix, origin);
            }
        });

        for (Map.Entry<String, List<ConsumeAccountInfoParam>> entry : userPrefix.entrySet()) {

            millionaireConsumerDao.batchAddConsumerAccount(entry.getValue().stream().sorted().collect(Collectors.toList()), entry.getKey());

        }
        redisTemplate.delete(totalInfo.stream().map(one -> buildConsumerKey(one.getCid())).collect(Collectors.toList()));




    }

    private void checkParam(ConsumeAccountParam consumeAccountParam) {
        if (consumeAccountParam.getAmount() < 0) {
            throw new RuntimeException("金额不能小于0");
        }
        if (consumeAccountParam.getCidAppIdSet().size() > 1000) {
            throw new RuntimeException("不支持1000个以上的数据");
        }
    }
}
